#ifndef __H_SESSION_M__
#define  __H_SESSION_M__

#include "util.hpp"
#include "room.hpp"

typedef enum{LOGIN, UNLOGIN} ss_status;

class session
{
public:
    session(uint64_t ssid) :_ssid(ssid) { DLOG("会话%p 创建成功",this); }
    ~session() { DLOG("会话%p 销毁成功",this); }
    uint64_t get_ssid() { return _ssid; }
    uint64_t get_user() { return _uid; }
    wsserver_t::timer_ptr& get_tp() { return _tp; }
    bool is_login() { return (_status == LOGIN);}

    void set_status(ss_status status) { _status = status; }
    void set_user(uint64_t uid) { _uid = uid; }
    void set_tp(const wsserver_t::timer_ptr& tp) { _tp = tp; }
private:
    uint64_t _ssid;
    uint64_t _uid;
    ss_status _status;
    wsserver_t::timer_ptr _tp;
};
#define SESSION_TIME 30000
#define SESSION_FOREVER -1

using session_ptr = shared_ptr<session>;
class session_manager
{
public:
    session_manager(wsserver_t* svr):_next_ssid(1), _server(svr)
        { DLOG("session会话管理模块初始化完成！"); }
    ~session_manager() { DLOG("session会话管理模块销毁完成！"); }
    // 创建session
    session_ptr create_session(uint64_t uid, ss_status status)
    {
        unique_lock<mutex> lock(_mutex);
        session_ptr ssp (new session(_next_ssid));
        _session.insert(make_pair(_next_ssid, ssp));
        ssp->set_user(uid);
        ssp->set_status(status);
        _next_ssid++;
        return ssp;
    }
    session_ptr get_session_by_ssid(uint64_t ssid)
    {
        unique_lock<mutex> lock(_mutex);
        auto it = _session.find(ssid);
        if(it == _session.end())
        {
            return session_ptr();
        }
        return it->second;
    }
    void remove_session(uint64_t ssid)
    {
        unique_lock<mutex> lock(_mutex);
        _session.erase(ssid);
    }
    void append_session(session_ptr& ssp)
    {
        unique_lock<mutex> lock(_mutex);
        _session.insert(make_pair(ssp->get_ssid(), ssp));
    }
    void set_session_expire_time(uint64_t ssid, int ms)
    {
        session_ptr ssp = get_session_by_ssid(ssid);
        if(ssp.get() == nullptr)
            { return ; }
        
        wsserver_t::timer_ptr tp = ssp->get_tp();
        if(tp.get() == nullptr && ms == SESSION_FOREVER)
            { return ; }
        else if(tp.get() == nullptr && ms != SESSION_FOREVER)
        {
            wsserver_t::timer_ptr ret_tp = _server->set_timer(ms, 
            bind(&session_manager::remove_session, this, ssid));
            ssp->set_tp(ret_tp);
        }
        else if(tp.get() != nullptr && ms == SESSION_FOREVER)
        {
            tp->cancel();   //删除定时任务
            ssp->set_tp( wsserver_t::timer_ptr());
            _server->set_timer(0, bind(&session_manager::append_session, this, ssp));

        }   
        else if(tp.get() != nullptr && ms != SESSION_FOREVER)
        {
            tp->cancel();   //删除定时任务
            _server->set_timer(0, bind(&session_manager::append_session, this, ssp));
            ssp->set_tp( wsserver_t::timer_ptr());

            wsserver_t::timer_ptr ret_tp = _server->set_timer(ms, 
            bind(&session_manager::remove_session, this, ssid));
            ssp->set_tp(ret_tp);
        }

    }
private:
    uint64_t _next_ssid;
    mutex _mutex;
    unordered_map<uint64_t, session_ptr> _session;
    wsserver_t* _server;
};

#endif